RAPPORT-ATL-2
Hibernate ?
Hibernate est un framework de persistance objet pour les applications Java. Il facilite le stockage et la récupération d'objets Java dans une base de données relationnelle. Hibernate permet de définir des classes Java qui représentent des tables de base de données et fournit des méthodes pour insérer, mettre à jour et supprimer des données de la base de données. Hibernate utilise des fichiers de configuration pour mapper les classes Java aux tables de la base de données et offre des fonctionnalités avancées telles que la mise en cache des données pour améliorer les performances des applications.
JPA ?
JPA, ou Java Persistence API, est une spécification de la plateforme Java EE qui définit un ensemble de normes pour la gestion de la persistance des données dans les applications Java. JPA permet aux développeurs de manipuler des données de manière objet, en évitant le besoin de coder des requêtes SQL à la main.
JPA est souvent utilisé en conjonction avec des frameworks d'ORM (Object-Relational Mapping) tels que Hibernate pour offrir une solution complète de gestion de la persistance des données dans les applications Java. L'utilisation de JPA permet de réduire considérablement le temps et les efforts nécessaires pour développer des applications de gestion de données, en offrant une approche simplifiée et standardisée.
Hibernate-JPA Structure
Technologies Utiliser
- Hibernate : 5.6.1.final
- MariaDB-Client : 3.1.2
- JDK : jdk-17
Structure de Project :
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── ynabouzi
│ │ └── atelier2
│ │ ├── controllers
│ │ │ ├── mainDAO.java
│ │ │ ├── RegistrationDAO.java
│ │ │ └── StudentDAO.java
│ │ ├── helper
│ │ │ └── MainHelper.java
│ │ ├── main.java
│ │ ├── manager
│ │ │ └── EntityManagerHelper.java
│ │ └── models
│ │ ├── Registration.java
│ │ └── Student.java
│ ├── resources
│ │ ├── log4j2.properties
│ │ ├── log4j2.xml.bak
│ │ └── META-INF
│ │ ├── hibernate.xml.bak
│ │ └── persistence.xml
│ └── webapp
│ ├── index.jsp
│ └── WEB-INF
│ └── web.xml
└── test
├── java
└── resources
18 directories, 19 filessrc/main/java: Ce dossier contient le code source principal en Java de l'application, comprenant des packages pour les contrôleurs, les DAO, les helpers et les modèles.
src/main/resources: Ce dossier contient des fichiers de configuration et d'autres ressources utilisées par l'application, y compris le fichierpersistence.xmlpour la configuration de JPA/Hibernate et le fichierweb.xmlpour la configuration des servlets et des filtres.
src/main/webapp: Ce dossier contient les ressources de l'application Web, y compris les fichiers JSP et les éléments statiques tels que les fichiers CSS et JavaScript.
src/test: Ce dossier contient du code et des ressources de test pour l'application, y compris des tests JUnit et des fichiers de configuration de test.
MVC
Models
- Registration
package com.ynabouzi.atelier2.models;
import javax.persistence.*;
import lombok.*;
import java.util.Date;
@Data
@NoArgsConstructor
@ToString
@AllArgsConstructor
@Entity
@NamedQuery(name = "AllRegistrations", query = "SELECT e FROM com.ynabouzi.atelier2.models.Registration e")
@NamedQuery(name = "AllRegistrationByStudentId", query = "SELECT e from com.ynabouzi.atelier2.models.Registration e where e.Student.Id_std=?1")
@Table(name = "registration", schema = "ATELIER2")
public class Registration {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "Id_reg", nullable = false)
private long Id_reg;
@Basic
@Column(name = "RegDate", nullable = true)
private Date RegDate;
@Basic
@Column(name = "Grouped", nullable = true, length = 30)
private String Grouped;
@Basic
@Column(name = "Level", nullable = true, length = 30)
private String Level;
@Basic
@Column(name = "Major", nullable = true, length = 30)
private String Major;
// @Basic
// @Column(name = "Student_id")
// private long Student_id;
@ManyToOne(fetch = FetchType.LAZY)
@ToString.Exclude
@JoinColumn(name = "Student_id", referencedColumnName = "Id_std")
private Student Student;
}Ce fichier contient une classe qui définit l'entité "Inscription" du projet. Il peut contenir des propriétés pour stocker les données relatives à cette entité, telles que l'identifiant de l'inscription, l'identifiant de l'étudiant associé, la date d'inscription, etc.
- Student
package com.ynabouzi.atelier2.models;
import javax.persistence.*;
import lombok.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Data
@NoArgsConstructor
@ToString
@AllArgsConstructor
@NamedQuery(name = "AllStudents", query = "SELECT e FROM com.ynabouzi.atelier2.models.Student e")
@NamedQuery(name = "AllStudentsByLvl", query = "SELECT e FROM Student e WHERE e.Id_std in (select r.Student.Id_std from Registration r where r.Level = ?1)")
@Entity
@Table(name = "student", schema = "ATELIER2")
public class Student {
// this is commented so i can have custom ID
// @GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "Id_std", nullable = false)
private long Id_std;
@Basic
@Column(name = "LastName", nullable = true, length = 20)
private String LastName;
@Basic
@Column(name = "FirstName", nullable = true, length = 20)
private String FirstName;
@Basic
@Column(name = "CIN", nullable = true, length = 20)
private String CIN;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "Student",orphanRemoval = true)
@ToString.Exclude
private List<Registration> re = new ArrayList<>();
}Ce fichier contient une classe qui définit l'entité "Étudiant" du projet. Il peut contenir des propriétés pour stocker les données relatives à cette entité, telles que l'identifiant de l'étudiant, le nom de l'étudiant, le CINl, etc.
Code 1 - Classe Etudiant:
- Représente les étudiants dans le système
- Champs pour l'identifiant, le nom, le prénom et le CIN de chaque étudiant
- Champs de type
Listpour stocker les inscriptions de chaque étudiant
- Annotations telles que
@Entity,@Table, et@Columnsont utilisées pour spécifier la table de la base de données correspondante et les colonnes associées
Code 2 - Classe Inscription:
- Représente une inscription d'un étudiant à un cours
- Champs pour l'identifiant, la date d'inscription, le niveau, le groupe et la spécialité de l'inscription
- Champ de type
Etudiantpour associer une inscription à un étudiant particulier
- Annotation
@ManyToOneindique une relation many-to-one entre les classesEtudiantetInscription
Hibernate / Persistence Config
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="default">
<class> com.ynabouzi.atelier2.models.Student</class>
<class> com.ynabouzi.atelier2.models.Registration</class>
<properties>
<property name="jakarta.persistence.jdbc.url" value="jdbc:mariadb://localhost:3306/ATELIER2?createDatabaseIfNotExist=true"/>
<property name="jakarta.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver"/>
<property name="jakarta.persistence.jdbc.user" value="abmola"/>
<property name="jakarta.persistence.jdbc.password" value="yasser1234"/>
<property name="jakarta.persistence.schema-generation.database.action" value="create-drop"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MariaDB10Dialect"/>
<property name="show_sql" value="false"/>
<property name="format_sql" value="true"/>
<property name="hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>- Ce fichier XML contient la configuration de la persistance pour l'application.
- Le nom de l'unité de persistance est défini comme
default.
- Les propriétés de connexion à la base de données sont spécifiées, telles que l'URL de la base de données, le nom d'utilisateur et le mot de passe. Les propriétés sont mises en évidence en gras et avec des ````.
- La propriété
jakarta.persistence.schema-generation.database.actionest définie surcreate-drop, ce qui signifie que le schéma de la base de données sera créé et abandonné à chaque fois que l'application est déployée.
- La propriété
hibernate.dialectest définie surorg.hibernate.dialect.MariaDB10Dialect, qui spécifie le dialecte Hibernate à utiliser avec la base de données MariaDB.
- Les propriétés
show_sqletformat_sqlsont définies pour contrôler l'affichage de la requête SQL générée par Hibernate.
Creation de DB
Le fichier XML fournit les détails de configuration pour la persistence-unit nommée "default". La propriété jakarta.persistence.jdbc.urlest définie pour créer automatiquement une base de données avec le nom ATELIER2 si elle n'existe pas déjà lors de la première exécution. La propriété jakarta.persistence.schema-generation.database.actionest définie sur "create-drop", ce qui signifie que la base de données est créée et supprimée à chaque fois que l'application est démarrée. Ainsi, en utilisant ce fichier de configuration, la base de données est
créée automatiquement lors de la première exécution de l'application, même si elle n'existe pas déjà.
Anyways
- Student Table :
create table student
(
Id_std bigint not null
primary key,
CIN varchar(20) null,
FirstName varchar(20) null,
LastName varchar(20) null
);- Registration Table :
create table registration
(
Id_reg bigint auto_increment
primary key,
Grouped varchar(30) null,
Level varchar(30) null,
Major varchar(30) null,
RegDate datetime(6) null,
Student_id bigint null,
constraint FK25ucw75sqymkkwjugi3pu0nar
foreign key (Student_id) references student (Id_std)
);- Entity Relationship Diagram :

Controllers
DBmanager
package com.ynabouzi.atelier2.manager;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class EntityManagerHelper {
private static final EntityManagerFactory emf;
static {
emf = Persistence.createEntityManagerFactory("default");
}
public static EntityManager getEntityManager() {
return emf.createEntityManager();
}
}EntityManagerHelperest une classe qui fournit une méthode pour obtenir une instance d'un objetEntityManager.
- Il utilise une instance statique de la classe
EntityManagerFactorypour créer une instance d'unEntityManager.
- La création de l'objet
EntityManagerFactoryest basée sur le nom de l'unité de persistence"default", qui correspond au nom spécifié dans le fichierpersistence.xml.
getEntityManager()retourne une nouvelle instance d'unEntityManagerà chaque appel.
- L'utilisation d'un
EntityManagerest nécessaire pour interagir avec la base de données à travers JPA.
DAO
Interface mainDAO<T> :
- La classe utilise la notion de génériques pour rendre sa fonctionnalité réutilisable pour n'importe quel type T.
- Elle contient six méthodes :
CreateAll,ShowAll,ShowByID,DeleteByID,UpdateByIDetFindByID.
package com.ynabouzi.atelier2.controllers;
import com.ynabouzi.atelier2.models.Student;
import java.util.List;
public interface mainDAO<T> {
public void CreateAll(List<T> Objs);
public void ShowAll();
public void ShowByID(long id);
public void DeleteByID(long id);
void UpdateByID(long id, T toChangeTo);
public T FindByID(long id);
}Classe RegistrationDAO :
- Elle implémente l'interface
mainDAOpour le typeRegistration.
- Elle utilise l'annotation
@PersistenceContextpour injecter unEntityManagerqui est utilisé dans les méthodes de l'interface.
package com.ynabouzi.atelier2.controllers;
import com.ynabouzi.atelier2.manager.EntityManagerHelper;
import com.ynabouzi.atelier2.models.Registration;
import com.ynabouzi.atelier2.models.Student;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.Date;
import java.util.List;
public class RegistrationDAO implements mainDAO<Registration>{
@PersistenceContext(unitName = "default")
private static EntityManager em;
@Override
public void CreateAll(List<Registration> Objs) {
em = EntityManagerHelper.getEntityManager();
System.out.println("! Inserting Data !\n==================================================");
try {
em.getTransaction().begin();
for (Registration re : Objs)
{
em.persist(re);
}
em.getTransaction().commit();
System.out.println("! Opperation Successful !\n==================================================");
}catch (Exception e)
{
em.getTransaction().rollback();
System.out.println("Opperation Unsuccessful");
System.out.println("Here are some errors that might help\n"+e);
} finally {
em.close();
}
}
@Override
public void ShowAll() {
em = EntityManagerHelper.getEntityManager();
try {
em.getTransaction().begin();
TypedQuery<Registration> Regs = em.createNamedQuery("AllRegistrations", Registration.class);
for(Registration reg : Regs.getResultList())
{
System.out.println(reg.toString());
}
System.out.println("! Opperation Successful !");
}catch (Exception e)
{
em.getTransaction().rollback();
System.out.println("Opperation Unsuccessful");
System.out.println("Here are some errors that might help\n"+e);
} finally {
em.close();
}
}
@Override
public void ShowByID(long id) {
em = EntityManagerHelper.getEntityManager();
try {
em.getTransaction().begin();
Registration reg = em.find(Registration.class, id);
if (reg == null){
System.out.println("No registration found by the id => "+id);
}
else {
System.out.println(reg);
}
System.out.println("! Opperation Successful !");
}catch (Exception e)
{
em.getTransaction().rollback();
System.out.println("Opperation Unsuccessful");
System.out.println("Here are some errors that might help\n"+e);
} finally {
em.close();
}
}
@Override
public void DeleteByID(long id) {
em = EntityManagerHelper.getEntityManager();
try {
em.getTransaction().begin();
Registration reg = em.find(Registration.class, id);
if (reg == null){
System.out.println("No registration found by the id => "+id);
}
else {
em.remove(reg);
System.out.println("The Registration by the id "+id+" has been removed successfully !");
em.getTransaction().commit();
}
System.out.println("! Opperation Successful !");
}catch (Exception e)
{
em.getTransaction().rollback();
System.out.println("Opperation Unsuccessful");
System.out.println("Here are some errors that might help\n"+e);
} finally {
em.close();
}
}
@Override
public void UpdateByID(long id, Registration toChangeTo) {
em = EntityManagerHelper.getEntityManager();
try {
em.getTransaction().begin();
Registration reg = em.find(Registration.class, id);
if (reg == null){
System.out.println("No student found by the id => "+id);
}
else {
String tmp = reg.toString();
Date RegDate = toChangeTo.getRegDate() != null ? toChangeTo.getRegDate() : reg.getRegDate();
String Group = toChangeTo.getGrouped() != null ? toChangeTo.getGrouped() : reg.getGrouped();
String Major = toChangeTo.getMajor() != null ? toChangeTo.getMajor() : reg.getMajor();
String Level = toChangeTo.getLevel() != null ? toChangeTo.getLevel() : reg.getLevel();
reg.setRegDate(RegDate);
reg.setGrouped(Group);
reg.setMajor(Major);
reg.setLevel(Level);
System.out.println("Before "+tmp);
em.getTransaction().commit();
System.out.println("The Registration by the id "+id+" has been updated successfully !");
System.out.println("after "+reg.toString());
}
System.out.println("! Opperation Successful !");
}catch (Exception e)
{
em.getTransaction().rollback();
System.out.println("Opperation Unsuccessful");
System.out.println("Here are some errors that might help\n"+e);
} finally {
em.close();
}
}
public void ShowRegByStudentId(long id) {
em = EntityManagerHelper.getEntityManager();
try {
em.getTransaction().begin();
TypedQuery<Registration> Regs = em.createNamedQuery("AllRegistrationByStudentId", Registration.class);
Regs.setParameter(1, id);
if (Regs.getResultList().isEmpty())
{
System.out.println("No Registrations for the "+id+" yet !");
}
else{
System.out.println("All Registrations for the Student"+id+" are :\n==================================================");
for (Registration reg : Regs.getResultList()) {
System.out.println(reg);
}
}
System.out.println("! Opperation Successful !\n==================================================");
}catch (Exception e)
{
em.getTransaction().rollback();
System.out.println("Opperation Unsuccessful");
System.out.println("Here are some errors that might help\n"+e);
} finally {
em.close();
}
}
@Override
public Registration FindByID(long id) {
em = EntityManagerHelper.getEntityManager();
try {
em.getTransaction().begin();
Registration reg = em.find(Registration.class, id);
if (reg == null){
System.out.println("No student found by the id => "+id);
return reg;
}
else {
System.out.println("! Opperation Successful !");
return reg;
}
}catch (Exception e)
{
em.getTransaction().rollback();
System.out.println("Opperation Unsuccessful");
System.out.println("Here are some errors that might help\n"+e);
} finally {
em.close();
}
return null; }
}Classe StudentDAO :
- Elle implémente l'interface
mainDAOpour le typeStudent.
- Elle utilise l'annotation
@PersistenceContextpour injecter unEntityManagerqui est utilisé dans les méthodes de l'interface.public class StudentDAO implements mainDAO<Student>{ @PersistenceContext(unitName = "default") private static EntityManager em; @Override public void CreateAll(List<Student> Objs) { em = EntityManagerHelper.getEntityManager(); System.out.println("! Inserting Data !\n=================================================="); try{ em.getTransaction().begin(); for (Student std : Objs) { em.persist(std); } em.getTransaction().commit(); System.out.println("! Opperation Successful !\n=================================================="); } catch (Exception e) { em.getTransaction().rollback(); System.out.println("Opperation Unsuccessful"); System.out.println("Here are some errors that might help\n"+e); } finally { em.close(); } } @Override public void ShowAll() { em = EntityManagerHelper.getEntityManager(); try { em.getTransaction().begin(); TypedQuery<Student> Students = em.createNamedQuery("AllStudents", Student.class); System.out.println("! Showing All students !\n=================================================="); for(Student std : Students.getResultList()) { System.out.println(std.toString()); } System.out.println("! Opperation Successful !\n=================================================="); }catch (Exception e) { em.getTransaction().rollback(); System.out.println("Opperation Unsuccessful"); System.out.println("Here are some errors that might help\n"+e); } finally { em.close(); } } @Override public void ShowByID(long id) { em = EntityManagerHelper.getEntityManager(); try { em.getTransaction().begin(); Student std = em.find(Student.class, id); if (std == null){ System.out.println("No student found by the id => "+id); } else { System.out.println(std); } System.out.println("! Opperation Successful !"); }catch (Exception e) { em.getTransaction().rollback(); System.out.println("Opperation Unsuccessful"); System.out.println("Here are some errors that might help\n"+e); } finally { em.close(); } } @Override public void DeleteByID(long id) { em = EntityManagerHelper.getEntityManager(); try { em.getTransaction().begin(); Student std = em.find(Student.class, id); if (std == null){ System.out.println("No student found by the id => "+id); } else { em.remove(std); System.out.println("The Student by the id "+id+" has been removed successfully !\n=================================================="); em.getTransaction().commit(); } System.out.println("! Opperation Successful !\n=================================================="); }catch (Exception e) { em.getTransaction().rollback(); System.out.println("Opperation Unsuccessful"); System.out.println("Here are some errors that might help\n"+e); } finally { em.close(); } } @Override public void UpdateByID(long id, Student toChangeTo) { em = EntityManagerHelper.getEntityManager(); try { em.getTransaction().begin(); Student std = em.find(Student.class, id); if (std == null){ System.out.println("No student found by the id => "+id); } else { String tmp = std.toString(); String FirstName = toChangeTo.getFirstName() != null ? toChangeTo.getFirstName() : std.getFirstName(); String LastName = toChangeTo.getLastName() != null ? toChangeTo.getLastName() : std.getLastName(); String CIN = toChangeTo.getCIN() != null ? toChangeTo.getCIN() : std.getCIN(); List<Registration> Re = toChangeTo.getRe() != null && !toChangeTo.getRe().isEmpty() ? toChangeTo.getRe() : std.getRe(); std.setFirstName(FirstName); std.setLastName(LastName); std.setCIN(CIN); std.setRe(Re); System.out.println("==================================================\nBefore "+tmp); em.getTransaction().commit(); System.out.println("The Student by the id "+id+" has been updated successfully !"); System.out.println("after "+std.toString()+"\n=================================================="); } System.out.println("! Opperation Successful !\n=================================================="); }catch (Exception e) { em.getTransaction().rollback(); System.out.println("Opperation Unsuccessful"); System.out.println("Here are some errors that might help\n"+e); } finally { em.close(); } } public void ShowStudentsByLvl(String lvl) { em = EntityManagerHelper.getEntityManager(); try { em.getTransaction().begin(); TypedQuery<Student> Students = em.createNamedQuery("AllStudentsByLvl", Student.class); Students.setParameter(1, lvl); if (Students.getResultList().isEmpty()) { System.out.println("No Students in the "+lvl+" of education yet !"); } else{ System.out.println("All Students in the "+lvl+" of education are :"); for (Student std : Students.getResultList()) { System.out.println(std); } } System.out.println("! Opperation Successful !"); }catch (Exception e) { em.getTransaction().rollback(); System.out.println("Opperation Unsuccessful"); System.out.println("Here are some errors that might help\n"+e); } finally { em.close(); } } @Override public Student FindByID(long id) { em = EntityManagerHelper.getEntityManager(); try { em.getTransaction().begin(); Student std = em.find(Student.class, id); if (std == null){ System.out.println("No student found by the id => "+id); return std; } else { System.out.println("! Opperation Successful !"); return std; } }catch (Exception e) { em.getTransaction().rollback(); System.out.println("Opperation Unsuccessful"); System.out.println("Here are some errors that might help\n"+e); } finally { em.close(); } return null; } }
Main
public class main {
private static void pressEnterToContinue()
{
System.out.println("Press Enter key to continue...");
try
{
System.in.read();
}
catch(Exception e)
{}
}
public static void main(String[] args) {
System.out.println("! Creating Databases !\n==================================================");
StudentDAO Stddao = new StudentDAO();
RegistrationDAO Regdao = new RegistrationDAO();
MainHelper Helper = new MainHelper();
// Question 6 : Let's Create 3 Students
Stddao.CreateAll(Helper.CreateStudents());
// Question 7 : List All Students
Stddao.ShowAll();
// Question 8 : Listing student id 44 Registrations
Registration AnotherOne = new Registration();
List<Registration> regs = new ArrayList<>();
regs.addAll(Helper.CreateReg(Stddao.FindByID(44)));
AnotherOne.setGrouped("Group7");
AnotherOne.setMajor("GPEE");
AnotherOne.setLevel("3eme");
AnotherOne.setRegDate(new Date(100,5,10));
AnotherOne.setStudent(Stddao.FindByID(88));
regs.add(AnotherOne);
Regdao.CreateAll(regs);
Regdao.ShowRegByStudentId(44);
// Question 9 : Deleting student by id
Stddao.DeleteByID(60);
// Question 10 : Update a student informations
Student change = new Student();
change.setFirstName("Hamza");
change.setCIN("AS6865");
Stddao.UpdateByID(44,change);
//Question 11 : Listing Students by level
Stddao.ShowStudentsByLvl("3eme");
pressEnterToContinue();
}
}Result

Ressources
- JAVA DOC : HERE
- SOURCE CODE : HERE
Made with Love 🦢
by @NBGamer

